namespace AForge.Imaging
{
	using System;
	using System.Drawing;
	using System.Drawing.Imaging;
	using AForge.Math;

	/// <summary>
	/// Gather statistics about the image
	/// </summary>
	public class ImageStatistics
	{
		private Histogram red;
		private Histogram green;
		private Histogram blue;
		private Histogram gray;
		private HistogramD saturation;
		private HistogramD luminance;

		private int pixels;
		private bool grayscale;

        private bool Scale = false;
        private Single ScaleSlope, ScaleIntercept;


		// Red property
		public Histogram Red
		{
			get { return red; }
		}
		// Green property
		public Histogram Green
		{
			get { return green; }
		}
		// Blue property
		public Histogram Blue
		{
			get { return blue; }
		}
		// Gray property
		public Histogram Gray
		{
			get { return gray; }
		}
		// Saturation property
		public HistogramD Saturation
		{
			get { return saturation; }
		}
		// Luminance property
		public HistogramD Luminance
		{
			get { return luminance; }
		}
		// PixelsCount property
		public int PixelsCount
		{
			get { return pixels; }
		}
		// IsGrayscale property
		public bool IsGrayscale
		{
			get { return grayscale; }
		}


		// Constructors
        public ImageStatistics(Bitmap image, bool scale, float scaleslope, float scaleintercept)
            : this(image, false, scale, scaleslope, scaleintercept)
		{
		}
		public ImageStatistics(Bitmap image, bool collectHSL, bool scales, Single ScaleSlope, Single ScaleIntercept)
		{
			// get image size
			int width = image.Width;
			int height = image.Height;

            this.Scale = scales;
            this.ScaleIntercept = ScaleIntercept;
            this.ScaleSlope = ScaleSlope;

			pixels = width * height;

			if (grayscale = (image.PixelFormat == PixelFormat.Format8bppIndexed))
			{
				// lock bitmap data
				BitmapData imgData = image.LockBits(
					new Rectangle(0, 0, width, height),
					ImageLockMode.ReadOnly,
					PixelFormat.Format8bppIndexed);

				// alloc arrays
				int[] g = new int[256];

				int offset = imgData.Stride - width;

				// do the job
				unsafe
				{
					byte * p = (byte *) imgData.Scan0.ToPointer();

					// for each pixel
					for (int y = 0; y < height; y++)
					{
						// for each pixel
						for (int x = 0; x < width; x++, p ++)
						{
                            if (*p !=0) //modified for mri
							    g[*p]++;
						}
						p += offset;
					}
				}
				// unlock image data
				image.UnlockBits(imgData);

				gray = new Histogram(g,scales,ScaleSlope,ScaleIntercept);
			}
			else
			{
				// lock bitmap data
                    BitmapData imgData = image.LockBits(
					new Rectangle(0, 0, width, height),
					ImageLockMode.ReadOnly,
					PixelFormat.Format24bppRgb);

				// alloc arrays
				int[]	r = new int[256];
				int[]	g = new int[256];
				int[]	b = new int[256];

				int[]	s = new int[256];
				int[]	l = new int[256];
				RGB		rgb = new RGB();
				HSL		hsl = new HSL();

				int offset = imgData.Stride - width * 3;

				// do the job
				unsafe
				{
					byte * p = (byte *) imgData.Scan0.ToPointer();

					// for each line
					for (int y = 0; y < height; y++)
					{
						// for each pixel
						for (int x = 0; x < width; x++, p += 3)
						{
                      if (p[RGB.R] != 0)
                            {
                                r[p[RGB.R]]++;
                                g[p[RGB.G]]++;
                                b[p[RGB.B]]++;


                                if (collectHSL)
                                {
                                    rgb.Red = p[RGB.R];
                                      rgb.Green = p[RGB.G];
                                    rgb.Blue = p[RGB.B];

                                    if (collectHSL)
                                    {
                                        AForge.Imaging.ColorConverter.RGB2HSL(rgb, hsl);

                                        s[(int)(hsl.Saturation * 255)]++;
                                        l[(int)(hsl.Luminance * 255)]++;
                                    }
                                }
                            }
						}
						p += offset;
					}
				}
				// unlock image data
				image.UnlockBits(imgData);
                //global::System.Windows.Forms.MessageBox.Show(scale.ToString());
				red		= new Histogram(r,scales,ScaleSlope,ScaleIntercept);
				green	= new Histogram(g,scales,ScaleSlope,ScaleIntercept);
				blue	= new Histogram(b,scales,ScaleSlope,ScaleIntercept);

				if (collectHSL)
				{
					saturation = new HistogramD(s, new RangeD(0, 1),scales, ScaleSlope,ScaleIntercept);
					luminance = new HistogramD(l, new RangeD(0, 1),Scale,ScaleSlope,ScaleIntercept);
				}
			}
		}
	}
}
